package com.itita.ww2.model.worldmap;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.itita.ww2.redis.RedisUtil;
import com.itita.ww2.redis.cache.Table;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.itita.ww2.data.WorldMapConfig;
import com.itita.ww2.model.interfaces.IModelUpdater;
import com.itita.ww2.model.user.UserProfile;
import com.itita.ww2.utils.DataUtil;

/**
 * 玩家的解锁情况(不存储,只操作数据)
 * @author NorthLan
 *
 */
public class UserUnlockDataMgr implements IModelUpdater {
	private UserProfile userProfile;
	private int uid;
	private Table table;

	public UserUnlockDataMgr(UserProfile userProfile, Table table) {
		this.userProfile = userProfile;
		this.uid = userProfile.getUid();
		this.table = table;
	}

	/**
	 * 解锁区块,不包含区块内城池
	 */
	public boolean unlockBlock(int blockId) {
		Map<Integer, List<Integer>> data = getUnlockData();
		// 已经解锁过
		if (isBlockUnlocked(data, blockId)) {
			return false;
		}
		// 检查各项前置条件
		ISFSObject blockCfg = WorldMapConfig.getBlockConfig(blockId);
		String preStr = blockCfg.getUtfString("pre_city");
		// pre_city
		int preBlockId = DataUtil.intValueOf(preStr.substring(1, preStr.indexOf('c')));
		int preCityId = DataUtil.intValueOf(preStr.substring(preStr.indexOf('c') + 1));
		if (!isCityUnlocked(data, preBlockId, preCityId)) {
			return false;
		}
		// cmd_lv
		if (userProfile.getUserInfo().getLevel() < blockCfg.getInt("lv_limit")) {
			return false;
		}
		// require_res
		if (!userProfile.getResManager().isResEnoughMulti(blockCfg.getSFSObject("require_res"))) {
			return false;
		}
		// 可以解锁,消耗资源
		userProfile.getResManager().operResWithMaxCheck(blockCfg.getSFSObject("require_res"), false);
		userProfile.getResManager().update();
		// 解锁
		data.put(blockId, new ArrayList<>());
		// 写入
		update(data);
		return true;
	}

	/**
	 * GM强制解锁一个区块
	 */
	public boolean gmUnlockBlock(int blockId) {
		Map<Integer, List<Integer>> data = getUnlockData();
		// 已经解锁过
		if (isBlockUnlocked(data, blockId)) {
			return false;
		}
		// 解锁
		data.put(blockId, new ArrayList<>());
		// 写入
		update(data);
		return true;
	}

	/**
	 * 解锁某区域的某个城
	 */
	public boolean unlockCity(int blockId, int cityId) {
		Map<Integer, List<Integer>> data = getUnlockData();
		// 区域没解锁
		if (!isBlockUnlocked(data, blockId)) {
			return false;
		}
		// 城池已解锁过
		if (isCityUnlocked(data, blockId, cityId)) {
			return false;
		}
		// 解锁城池
		data.get(blockId).add(cityId);
		// 写入
		update(data);
		return true;
	}

	/**
	 * GM 强制解锁一个 城市
	 * (还是需要前置条件的)
	 */
	public boolean gmUnlockCity(int blockId, int cityId) {
		return unlockCity(blockId, cityId);
	}

	/**
	 * 区域是否已解锁
	 */
	public boolean isBlockUnlocked(int blockId) {
		return isBlockUnlocked(getUnlockData(), blockId);
	}

	public static boolean isBlockUnlocked(Map<Integer, List<Integer>> data, int blockId) {
		return data.containsKey(blockId);
	}

	/**
	 * 城池是否已解锁
	 */
	public boolean isCityUnlocked(int blockId, int cityId) {
		return isCityUnlocked(getUnlockData(), blockId, cityId);
	}

	public static boolean isCityUnlocked(Map<Integer, List<Integer>> data, int blockId, int cityId) {
		if (!data.containsKey(blockId)) {
			return false;
		}
		if (!data.get(blockId).contains(cityId)) {
			return false;
		}
		return true;
	}

	public Map<Integer, List<Integer>> getUnlockData() {
		String ret = table.getValue(RedisUtil.genericKey(this.uid), "unlockData");
		return new GsonBuilder().create().fromJson(ret, new TypeToken<Map<Integer, List<Integer>>>() {
		}.getType());
	}

	public ISFSObject getUnlockDataObj() {
		return DataUtil.objValueOf(table.getValue(RedisUtil.genericKey(this.uid), "unlockData"));
	}

	/**
	 * 初始化(新用户)
	 */
	public void initialize(ISFSObject data) {
		table.setValue(RedisUtil.genericKey(this.uid), "unlockData", data.toJson());
	}

	@Override
	public <T> void update(T t) {
		table.setValue(RedisUtil.genericKey(this.uid), "unlockData", new GsonBuilder().create().toJson(t));
	}
}
